﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using ManagedService;
using System.Threading;
using System.IO;
using System.Reflection;
using Interfaces;
using System.MessagingCE;
using Microsoft.Win32;

namespace ServiceHost
{
    class ServiceHost : ServiceApplication
    {
        public IPositionOriginator Instance { get; private set; }
        public string AssemblyPath { get; private set; }

        private Dictionary<string, MessageQueue> mQueues;

        public ServiceHost(bool start, string path)
        {
            mQueues = new Dictionary<string, MessageQueue>();
            try
            {
                FileInfo file = new FileInfo(path);
                if (file.Exists)
                {
                    Assembly mAssembly = Assembly.LoadFrom(path);
                    foreach (Type mType in mAssembly.GetTypes())
                    {
                        if (mType.IsPublic)
                        {
                            //Only look at non-abstract types
                            if (!mType.IsAbstract)
                            {
                                Type tInterface = null;

                                //Gets a type object of the interface we need the plugins to match
                                foreach (Type t in mType.GetInterfaces())
                                {
                                    if (t.FullName == "Interfaces.IPositionOriginator")
                                        tInterface = t;
                                }

                                //Make sure the interface we want to use actually exists
                                if (tInterface != null)
                                {
                                    Instance = (IPositionOriginator)Activator.CreateInstance(mAssembly.GetType(mType.ToString()));
                                    AssemblyPath = path;
                                }
                                tInterface = null;

                                if (!start)
                                {
                                    RegistryKey mainkey = Registry.LocalMachine.OpenSubKey("Software\\ManagedServies");
                                    if (mainkey != null)
                                    {
                                        foreach (string guid in mainkey.GetSubKeyNames())
                                        {
                                            RegistryKey subKey = Registry.LocalMachine.OpenSubKey("Software\\ManagedServies\\" + guid);
                                            if (subKey.GetValue("ServiceName").ToString() == Instance.Name)
                                            {
                                                ServiceMessageHelper.SendMessage(guid, ServiceApplication.UM_QUIT_SERVICE);
                                                return;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else throw new FileNotFoundException();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }

            this.ServiceGuid = System.Guid.NewGuid();
            this.ServiceName = Instance.Name;

            Instance.NewSignalEvent += new NewSignalEventHandler(Instance_SignalEvent);
            Instance.BestSignalEvent += new BestSignalEventHandler(Instance_SignalEvent);

            Instance.Initialize();
            Instance.SetRadioOn();

            this.RegisterService();
        }

        void Instance_SignalEvent(object sender, PositionEventArgs e)
        {
            if (!mQueues.ContainsKey("SignalEvent"))
            {
                mQueues.Add("SignalEvent", new MessageQueue(false, "SignalEvent"));
            }
            mQueues["SignalEvent"].Send(new SignalEventMessage(e));
        }
    }
}
